package com.cgrs572.shortlink.admin.config;

import com.cgrs572.shortlink.admin.common.biz.user.UserFlowRiskControlFilter;
import com.cgrs572.shortlink.admin.common.biz.user.UserTransmitFilter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * 用户配置自动装配
 */
@Configuration
public class UserConfiguration {

    /**
     * 将用户信息传递过滤器注册到Spring的IOC容器中
     * 在微服务中注册一个名为UserTransmitFilter的过滤器，并将其应用到指定的URL请求上
     * FilterRegistrationBean<T extends Filter>---用于注册和配置一个过滤器,泛型为要注册的过滤器
     * @return
     */
    @Bean
    public FilterRegistrationBean<UserTransmitFilter> globalUserTransmitFilter() {
        // 创建一个FilterRegistrationBean对象，用于注册和配置过滤器
        FilterRegistrationBean<UserTransmitFilter> registration = new FilterRegistrationBean<>();
        // 配置和注册过滤器,参数为指定的过滤器实例
        registration.setFilter(new UserTransmitFilter());
        // 设置过滤器UserTransmitFilter的拦截哪些请求
        registration.addUrlPatterns("/*");
        // 设置过滤器的执行顺序。数字越小，优先级越高. 数字最小为0
        registration.setOrder(0);
        return registration;
    }

    /**
     * 将用户操作流量风控过滤器注册到Spring的IOC容器中
     * 注解@ConditionalOnProperty:当name指定属性的属性值为havingValue的属性值时，该过滤器生效
     * 该注解缺点：若使用Nacos动态变更是否开启风控过滤时，此时该注解无法判断变更后的属性值，所以最好在代码内使用if判断
     */
    @Bean
    @ConditionalOnProperty(name = "short-link.flow-limit.enable", havingValue = "true")
    public FilterRegistrationBean<UserFlowRiskControlFilter> globalUserFlowRiskControlFilter(
            StringRedisTemplate stringRedisTemplate,
            UserFlowRiskControlConfiguration userFlowRiskControlConfiguration) {
        // 创建一个FilterRegistrationBean对象，用于注册和配置过滤器
        FilterRegistrationBean<UserFlowRiskControlFilter> registration = new FilterRegistrationBean<>();
        // 配置和注册过滤器,参数为指定的过滤器实例
        registration.setFilter(new UserFlowRiskControlFilter(stringRedisTemplate, userFlowRiskControlConfiguration));
        registration.addUrlPatterns("/*");// 设置过滤器UserFlowRiskControlFilter的拦截哪些请求
        registration.setOrder(10);// 设置过滤器的执行顺序。数字越小，优先级越高. 数字最小为0
        return registration;
    }

    /**
     * BCrypt密码加密
     * @return
     */
    @Bean
    public BCryptPasswordEncoder passwordEncoder() {
        // 参数 10 是强度（log rounds），越大越安全但越耗时，默认 10-12 即可
        return new BCryptPasswordEncoder(10);
    }
}

